﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "CmdCreateGRepModel.h"
#include "IBody.h"
#include "IMesh.h"
#include "IFace.h"
#include "IArc3d.h"
#include "IArc2d.h"
#include "IPlane.h"
#include "ILine3d.h"
#include "IUiView.h"
#include "Matrix4d.h"
#include "IPolygon.h"
#include "ICurve3d.h"
#include "IElement.h"
#include "IDocument.h"
#include "MathUtils.h"
#include "IEllipse3d.h"
#include "IPolyCurve.h"
#include "IModelLine.h"
#include "IModelView.h"
#include "IUiDocument.h"
#include "IRibbonGroup.h"
#include "IDirectShape.h"
#include "IPolyCurve3d.h"
#include "Coordinate3d.h"
#include "GmBodyBuilder.h"
#include "GbmpQuickCast.h"
#include "ISpiralLine3d.h"
#include "ITorusSurface.h"
#include "IGraphicsStyle.h"
#include "IGraphicsPoint.h"
#include "GbmpFileSystem.h"
#include "IGraphicsPlane.h"
#include "ModelViewEnums.h"
#include "ICommandManager.h"
#include "IAnnotationText.h"
#include "ITrimmedSurface.h"
#include "IUserTransaction.h"
#include "GcmpCommandState.h"
#include "IGraphicsCurve3d.h"
#include "IGraphicsPicture.h"
#include "IGraphicsBRepBody.h"
#include "IGraphicsBRepFace.h"
#include "IGraphicsBRepEdge.h"
#include "IGraphicsMeshBody.h"
#include "IGraphicsRichText.h"
#include "IGraphicsZoomFree.h"
#include "IGraphicsStyleData.h"
#include "IGraphicsNodeGroup.h"
#include "UiDocumentViewUtils.h"
#include "AlgorithmDiscretize.h"
#include "VisibilityTypeEnums.h"
#include "IVisualEffectManager.h"
#include "IGraphicsPolyCurve3d.h"
#include "IPureGraphicsElement.h"
#include "AlgorithmMeshOperate.h"
#include "IGraphicsElementShape.h"
#include "IGraphicsStyleManager.h"
#include "AlgorithmPolygonOperate.h"
#include "ICommandButtonDefinition.h"
#include "IControlDefinitionLibrary.h"
#include "AlgorithmBodyTopologyOperate.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "IGraphicsNodeStyleAndMaterialOverride.h"

#include <vector>
#include "GRepCommandIds.h"
#include "CommandRegister.h"
#include "SampleUIUtils.h"
#include "IElementModelShape.h"
#include "ViewSpecificElement.h"
#include "DetailLevelVisibilityFilter.h"
#include "GStyle\CustomizerGStyleManager.h"
#include "GZoomFreeTransformationComponent.h"
#include "ICanvas.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 


using namespace gcmp;
using namespace Sample;

REGISTER_COMMAND(CmdCreateGRepModel)

CmdCreateGRepModel::CmdCreateGRepModel() : CommandBase(ID_CMD_GREP_CREATE_MODEL) {}

bool CmdCreateGRepModel::IsEnabled() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

bool CmdCreateGRepModel::IsVisible() const
{
    return GcmpCommandState::IsInDocumentEnvironment();
}

namespace
{
    // 辅助工具类，根据序号获得示例模型摆放位置的坐标
    Vector3d GetPosition(int index)
    {
        int col = index / 3;
        int row = index % 3;
        return Vector3d(col * 2000, 9000 + row * 2000, 0);;
    }
}

/// 将生成的GRep分行分列移动为阵列排布，并且添加注释文字
void CmdCreateGRepModel::TransformAndMark(IDocument* pDocument, IGraphicsElementShape* pGraphicsElementShape, int i, std::wstring comments)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDocument, L"pDocument为空", L"GDMP", L"2024-03-30");
    DBG_WARN_AND_RETURN_VOID_UNLESS(pGraphicsElementShape, L"pGraphicsElementShape为空", L"GDMP", L"2024-03-30");

    std::wstring fontPath = FileSystem::GetExeDirPath() + L"FZLTHJW.TTF";
    Vector3d textPosition(0, -150, 0);
    Vector3d textDirection = Vector3d::UnitX;
    Vector3d textNormal = Vector3d::UnitZ;
    double textHeight = 60;

    AnnotationTextData textData = { comments, fontPath, textPosition, textDirection, textNormal, textHeight, 0, 1 };
    std::vector<OwnerPtr<IGraphicsText>> opGTexts = IAnnotationText::CreateGraphicsTexts(pDocument, textData);
    DBG_WARN_AND_RETURN_VOID_UNLESS(opGTexts.size() > 0, L"opGTexts为空", L"GDMP", L"2024-03-30");
    OwnerPtr<IGraphicsNodeGroup> opGGroupNode = IGraphicsNodeGroup::Create();
    DBG_WARN_AND_RETURN_VOID_UNLESS(opGGroupNode, L"opGGroupNode为空", L"GDMP", L"2024-03-30");
    for (auto &itor : opGTexts)
    {
        opGGroupNode->AddChild(TransferOwnership(itor));
    }
    pGraphicsElementShape->AddChild(TransferOwnership(opGGroupNode));

    Vector3d position = GetPosition(i);

    Matrix4d matrix;
    matrix.MakeTranslate(position);
    pGraphicsElementShape->Transform(matrix);
}

gcmp::OwnerPtr<gcmp::IAction> CmdCreateGRepModel::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    IUiDocument*  pUiDocument = UiDocumentViewUtils::GetCurrentUiDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocument, L"请打开文档", L"GDMP", L"2024-03-30");
    IDocument* pDocument = pUiDocument->GetDbDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDocument, L"请打开文档", L"GDMP", L"2024-03-30");
    IModelView* pModelView = UiDocumentViewUtils::GetCurrentModelView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pModelView, L"pModelView为空", L"GDMP", L"2024-03-30");

    OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(pDocument, L"创建拾取测试图元");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opTransaction, L"opTransaction为空", L"GDMP", L"2024-03-30");

    IVisualEffectManager* pVisualEffectMgr = IVisualEffectManager::Get();
    pVisualEffectMgr->ShowBothHatchAndMaterial(true);

    // index用于计算图元在阵列的位置
    static int index = 0;
    {
        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);

        // 创建三维螺旋线
        gcmp::Coordinate3d coord = gcmp::Coordinate3d(Vector3d::Zero, Vector3d::UnitX, Vector3d::UnitY);
        OwnerPtr<ICurve3d> opSpiralline = ISpiralLine3d::Create(coord, 500, Intervald(0, 5000), 0.3, 0.1);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSpiralline, L"opSpiralline为空", L"GDMP", L"2024-03-30");
        std::vector<const ICurve3d*> opSpines;
        opSpines.emplace_back(opSpiralline.get());

        OwnerPtr<IGraphicsCurve3d> opGCurve = IGraphicsCurve3d::Create(opSpiralline.get());

        // 创建截面轮廓
        OwnerPtr<IArc2d> opCircle = IArc2d::Create(Vector2d::Zero, 50, 0, Constants::MATH_2PI);
        OwnerPtr<IPolyCurve> opPolyCurve = IPolyCurve::Create();
        opPolyCurve->AddFrontCurve(TransferOwnership(opCircle));
        OwnerPtr<IPolygon> opPolygon = IPolygon::Create();
        opPolygon->AddPolyCurveByClone(opPolyCurve.get());

        // 创建扫掠体，并只显示为没有两端的空心管
        OwnerPtr<IBody> opSweepBody = GmBodyBuilder::CreateSweepBody(TransferOwnership(opPolygon), opSpines, Vector3d(0, 0, 1), SweepType::Upright);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opSweepBody, L"opSweepBody为空", L"GDMP", L"2024-03-30");
        OwnerPtr<IGraphicsBRepBody> opBRepShellBody = IGraphicsBRepBody::Create(TransferOwnership(opSweepBody));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opBRepShellBody, L"opBRepShellBody为空", L"GDMP", L"2024-03-30");

        int nodeId = 0;
        // IPureGraphicsElement图元用于最轻量化的单纯显示目的，因此不会自动设置GraphicsNodeId
        opBRepShellBody->SetId(GraphicsNodeId(nodeId++));

        for (int faceIndex = 0; faceIndex < opBRepShellBody->GetFaceCount(); ++faceIndex)
        {
            IGraphicsBRepFace* pGFace = opBRepShellBody->GetFaceFW(faceIndex);
            pGFace->SetId(GraphicsNodeId(nodeId++));
            if (pGFace->IsPlanar())
            {
                // 如果是扫掠体两端的平面，则隐藏两个面
                pGFace->SetVisibility(GraphicsNodeVisibility::Never);
            }
            else
            {
                // 如果是扫掠体的管面，需要设置面的两侧都可见
                pGFace->SetIsBackFaceVisible(true);
            }
        }
        for (int edgeIndex = 0; edgeIndex < opBRepShellBody->GetEdgeCount(); ++edgeIndex)
        {
            IGraphicsBRepEdge* pGEdge = opBRepShellBody->GetEdgeFW(edgeIndex);
            pGEdge->SetId(GraphicsNodeId(nodeId++));
            if (pGEdge->IsSeam())
            {
                // 如果是管面的接缝边，则隐藏该接缝边 
                pGEdge->SetVisibility(GraphicsNodeVisibility::Never);
            }
        }

        // 创建图形表达IGraphicsElementShape，并设置创建的扫掠体
        opGraphicsElementShape->AddChild(TransferOwnership(opBRepShellBody));

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"螺旋面");
        IPureGraphicsElement::Create(pDocument, TransferOwnership(opGraphicsElementShape));
    }

    index++;
    {
        // 创建一个魔方，准备三种颜色
        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
        std::vector<Color> colors = { Color::Red, Color::Yellow, Color::Blue };

        double cubeSize = 300;          // 魔方的大小
        int nodeId = 0;
        std::vector<IGraphicsStyle*> pGStyles;
        for (int i = 0; i < 3; i++)     // 魔方从上到下有三层
        {
            // 魔方的上下三层分别创建一个IGraphicsNodeGroup，用于整体管理每层方块的坐标和样式
            OwnerPtr<IGraphicsNodeGroup> opGNodeGroup = IGraphicsNodeGroup::Create();
            opGNodeGroup->SetId(GraphicsNodeId(nodeId++));

            // 创建 3 x 3 的方块
            for (int j = 0; j < 3; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    std::vector<Vector3d> points = { Vector3d::Zero, Vector3d(cubeSize, 0, 0), Vector3d(cubeSize, cubeSize, 0), Vector3d(0, cubeSize,0) };
                    OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBodyByPoints(points, cubeSize);
                    opBody->Translate(Vector3d(j*cubeSize, k*cubeSize, 0));
                    OwnerPtr<IGraphicsBRepBody> opBRepBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
                    // 将方块添加到IGraphicsNodeGroup
                    opGNodeGroup->AddChild(TransferOwnership(opBRepBody));
                }
            }
            // 创建坐标变换矩阵，将每层方块的IGraphicsNodeGroup移动到正确高度，并作旋转
            Matrix4d matrixRotate, matrixMove;
            matrixRotate.MakeRotate(Vector3d(cubeSize * 1.5, cubeSize * 1.5, 0), Vector3d::UnitZ, i * 0.3);
            matrixMove.MakeTranslate(Vector3d::UnitZ * cubeSize * i);
            // 对IGraphicsNodeGroup整体设置坐标变换
            opGNodeGroup->Transform(matrixRotate * matrixMove);

            // 创建图形样式，并对三层分别设置红黄蓝三色，然后整体设置到IGraphicsNodeGroup
            IGraphicsStyle* pGraphicsStyle = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
            OwnerPtr<IGraphicsStyleData> opGraphicsStyleData = pGraphicsStyle->GetGraphicsStyleData();
            pGStyles.emplace_back(pGraphicsStyle);
            Color color = colors.at(i);
            opGraphicsStyleData->Reset().SetColor(color).SetProjectionFaceHatchColor(color).SetProjectionLineColor(color).SetProjectionFaceHatchPattern(L"SOLID");
            pGraphicsStyle->SetGraphicsStyleData(*opGraphicsStyleData.get());
            // 对IGraphicsNodeGroup整体设置样式
            opGNodeGroup->SetGraphicsStyleId(pGraphicsStyle->GetElementId());
            opGraphicsElementShape->AddChild(TransferOwnership(opGNodeGroup));
        }

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"IGraphicsNodeGroup创建的魔方");
        IPureGraphicsElement* pPGE = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGraphicsElementShape));
        for (auto itor : pGStyles)
        {
            itor->SetOwnerId(pPGE->GetElementId());
        }
    }

    index++;
    {
        // 创建 3 x 3 的立方体阵列
        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);

        double cubeSize = 300;          // 魔方的大小
        for (int i = 0; i < 3; i++)     // 魔方从上到下有三层
        {
            // 魔方的上下三层分别创建一个IGraphicsNodeGroup，用于整体管理每层方块的坐标和样式
            OwnerPtr<IGraphicsNodeGroup> opGNodeGroup = IGraphicsNodeGroup::Create();
            OwnerPtr<IBody> opMergedBody;

            // 创建 3 x 3 的方块
            for (int j = 0; j < 3; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    std::vector<Vector3d> points = { Vector3d::Zero, Vector3d(cubeSize, 0, 0), Vector3d(cubeSize, cubeSize, 0), Vector3d(0, cubeSize,0) };
                    OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBodyByPoints(points, cubeSize);
                    opBody->Translate(Vector3d(j*cubeSize, k*cubeSize, 0));
                    if (opMergedBody)
                    {
                        opMergedBody = AlgorithmBodyTopologyOperate::BoolOperate(opMergedBody.get(), opBody.get(), BodyBooleanOperation::Unite);
                    }
                    else
                    {
                        opMergedBody = TransferOwnership(opBody);
                    }
                }
            }

            if (i == 1)
            {
                AlgorithmBodyTopologyOperate::MergeCoincideFace(opMergedBody);
            }
            else if (i == 2)
            {
                AlgorithmBodyTopologyOperate::MergeFaces(opMergedBody.get());
                AlgorithmBodyTopologyOperate::MergeEdges(opMergedBody.get());
            }
            // 将方块添加到IGraphicsNodeGroup
            OwnerPtr<IGraphicsBRepBody> opBRepBody = IGraphicsBRepBody::Create(TransferOwnership(opMergedBody));
            opGNodeGroup->AddChild(TransferOwnership(opBRepBody));

            // 创建坐标变换矩阵，将每层方块的IGraphicsNodeGroup移动到正确高度，并作旋转
            Matrix4d matrixMove;
            matrixMove.MakeTranslate(Vector3d::UnitZ * cubeSize * i * 3);
            // 对IGraphicsNodeGroup整体设置坐标变换
            opGNodeGroup->Transform(matrixMove);

            opGraphicsElementShape->AddChild(TransferOwnership(opGNodeGroup));
        }

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"上下三层体块做了不同方式的合并处理");
        IDirectShape* pDirectShape = IDirectShape::Create(pDocument, BuiltInCategoryUniIdentities::BICU_FORM);
        pDirectShape->SetGraphicsElementShape(TransferOwnership(opGraphicsElementShape));
    }

    index++;
    {
        IDirectShape* pDirectShape = IDirectShape::Create(pDocument, BuiltInCategoryUniIdentities::BICU_FORM);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDirectShape, L"pDirectShape为空", L"GDMP", L"2024-03-30");

        // 创建正方体立柱
        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGraphicsElementShape, L"opGraphicsElementShape为空", L"GDMP", L"2024-03-30");

        double columnHeight = 5000;

        std::vector<gcmp::Vector3d> points = { Vector3d(-50, -50, 0), Vector3d(50, -50, 0), Vector3d(50, 50, 0), Vector3d(-50, 50, 0), Vector3d(-50, -50, 0) };
        OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBodyByPoints(points, columnHeight);
        OwnerPtr<IGraphicsBRepBody> opGraphicsBRepBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGraphicsBRepBody, L"opGraphicsBRepBody为空", L"GDMP", L"2024-03-30");
        VisibilityType findMediam = (VisibilityType)((uint32_t)VisibilityType::VisibleInMedium | (uint32_t)VisibilityType::VisibleInFine);
        opGraphicsBRepBody->SetVisibilityFilter(NEW_AS_OWNER_PTR(DetailLevelVisibilityFilter, findMediam));
        opGraphicsElementShape->AddChild(TransferOwnership(opGraphicsBRepBody));

        // 在正方体中心创建等长结构分析线
        OwnerPtr<IGraphicsNodeGroup> opGGroup = IGraphicsNodeGroup::Create();
        opGGroup->SetVisibilityFilter(NEW_AS_OWNER_PTR(DetailLevelVisibilityFilter, VisibilityType::VisibleInCoarse));

        OwnerPtr<ILine3d> opLine = ILine3d::Create(Vector3d::Zero, Vector3d(0, 0, columnHeight));
        OwnerPtr<IGraphicsCurve3d> opGCurve3d = IGraphicsCurve3d::Create(opLine.get());
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGCurve3d, L"opGCurve3d为空", L"GDMP", L"2024-03-30");

        OwnerPtr<IGraphicsPoint> opGPoint0 = IGraphicsPoint::Create(Vector3d(0, 0, 0));
        OwnerPtr<IGraphicsPoint> opGPoint1 = IGraphicsPoint::Create(Vector3d(0, 0, columnHeight));

        opGGroup->AddChild(TransferOwnership(opGCurve3d));
        opGGroup->AddChild(TransferOwnership(opGPoint0));
        opGGroup->AddChild(TransferOwnership(opGPoint1));

        opGraphicsElementShape->AddChild(TransferOwnership(opGGroup));

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"创建有视图详细等级的方柱");
        pDirectShape->SetGraphicsElementShape(TransferOwnership(opGraphicsElementShape));
    }

    index++;
    {
        IDirectShape* pDirectShape = IDirectShape::Create(pDocument, BuiltInCategoryUniIdentities::BICU_FORM);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDirectShape, L"pDirectShape为空", L"GDMP", L"2024-03-30");

        // 创建Delaunay三角网格
        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGraphicsElementShape, L"opGraphicsElementShape为空", L"GDMP", L"2024-03-30");

        std::vector<gcmp::Vector3d> Vector3dArr;

        Vector3dArr.emplace_back(Vector3d(0, 0, 0));
        Vector3dArr.emplace_back(Vector3d(10, 0, 10));
        Vector3dArr.emplace_back(Vector3d(20, 0, 20));
        Vector3dArr.emplace_back(Vector3d(30, 0, 20));
        Vector3dArr.emplace_back(Vector3d(40, 0, 10));
        Vector3dArr.emplace_back(Vector3d(50, 0, 0));

        Vector3dArr.emplace_back(Vector3d(0, 10, 0));
        Vector3dArr.emplace_back(Vector3d(10, 10, 10));
        Vector3dArr.emplace_back(Vector3d(20, 10, 20));
        Vector3dArr.emplace_back(Vector3d(30, 10, 20));
        Vector3dArr.emplace_back(Vector3d(40, 10, 10));
        Vector3dArr.emplace_back(Vector3d(50, 10, 0));

        Vector3dArr.emplace_back(Vector3d(0, 20, 0));
        Vector3dArr.emplace_back(Vector3d(10, 20, 10));
        Vector3dArr.emplace_back(Vector3d(20, 20, 20));
        Vector3dArr.emplace_back(Vector3d(30, 20, 20));
        Vector3dArr.emplace_back(Vector3d(40, 20, 10));
        Vector3dArr.emplace_back(Vector3d(50, 20, 0));

        Vector3dArr.emplace_back(Vector3d(0, 30, 0));
        Vector3dArr.emplace_back(Vector3d(10, 30, 10));
        Vector3dArr.emplace_back(Vector3d(20, 30, 20));
        Vector3dArr.emplace_back(Vector3d(30, 30, 40));
        Vector3dArr.emplace_back(Vector3d(40, 30, 10));
        Vector3dArr.emplace_back(Vector3d(50, 30, 0));

        Vector3dArr.emplace_back(Vector3d(0, 40, 0));
        Vector3dArr.emplace_back(Vector3d(10, 40, 10));
        Vector3dArr.emplace_back(Vector3d(20, 40, 20));
        Vector3dArr.emplace_back(Vector3d(30, 40, 20));
        Vector3dArr.emplace_back(Vector3d(40, 40, 10));
        Vector3dArr.emplace_back(Vector3d(50, 40, 0));

        Vector3dArr.emplace_back(Vector3d(0, 50, 0));
        Vector3dArr.emplace_back(Vector3d(10, 50, 0));
        Vector3dArr.emplace_back(Vector3d(20, 50, 0));
        Vector3dArr.emplace_back(Vector3d(30, 50, 0));
        Vector3dArr.emplace_back(Vector3d(40, 50, 0));
        Vector3dArr.emplace_back(Vector3d(50, 50, 0));

        std::vector<unsigned int> var;
        OwnerPtr<IMesh> opDelaunay = AlgorithmMeshOperate::CreateDelaunayMeshFromPoints(Vector3dArr, var);
        Matrix4d scaleMatrix;
        scaleMatrix.MakeScale(Vector3d::Zero, 20);
        opDelaunay->Transform(scaleMatrix);

        // 图形节点
        OwnerPtr<IGraphicsMeshBody> opBRepShellBody = IGraphicsMeshBody::Create(TransferOwnership(opDelaunay));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opBRepShellBody, L"opBRepShellBody为空", L"GDMP", L"2024-03-30");

        opGraphicsElementShape->AddChild(TransferOwnership(opBRepShellBody));

        std::vector<Vector3d> points = { Vector3d::Zero, Vector3d(1000, 0, 0), Vector3d(1000, 1000, 0), Vector3d(0, 1000,0) };
        OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBodyByPoints(points, 800);
        OwnerPtr<IGraphicsBRepBody> opGraphicsBRepBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGraphicsBRepBody, L"opGraphicsBRepBody为空", L"GDMP", L"2024-03-30");

        opGraphicsElementShape->AddChild(TransferOwnership(opGraphicsBRepBody));

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"生成Delaunay三角网格");
        pDirectShape->SetGraphicsElementShape(TransferOwnership(opGraphicsElementShape));
    }

    index++;
    {
        IDirectShape* pDirectShape = IDirectShape::Create(pDocument, BuiltInCategoryUniIdentities::BICU_FORM);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDirectShape, L"pDirectShape为空", L"GDMP", L"2024-03-30");

        std::vector<Vector3d> vertices
        {
            { 0,0,0 },{ 20,30,50 },{ 700,700,-200 },{ -200,-200,0 },
            { -1000,-1000,0 },{ 1000,-1000,0 },{ 1000,1000,0 },{ -1000,1000,0 },
            { -899,-500,0 },{ 20.2,-200,0 },{ -600,600,300 },{ -1000,1000,1000 },
            { -500,-500,0 },{ -500,500,0 },{ 500,500,0 },{ 500,-500,0 }
        };

        std::vector<std::vector<Vector3d>> constraints
        {
            { { -1000,-1000,0 },{ 1000,-1000,0 },{ 1000,1000,0 },{ -1000,1000,0 } },
            { { -500,-500,0 },{ -500,500,0 },{ 500,500,0 },{ 500,-500,0 } }
        };

        OwnerPtr<IMesh> opMesh = AlgorithmMeshOperate::CreateXYTriangulation(constraints, vertices);

        Matrix4d matrix;
        matrix.MakeScale(Vector3d::Zero, 0.5);
        matrix.MakeTranslate(Vector3d(500, 500, 0));
        opMesh->Transform(matrix);

        //  离散点集约束Delaunary三角化，包含内环
        OwnerPtr<IGraphicsMeshBody> opBRepShellBody = IGraphicsMeshBody::Create(TransferOwnership(opMesh));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opBRepShellBody, L"opBRepShellBody为空", L"GDMP", L"2024-03-30");

        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGraphicsElementShape, L"opGraphicsElementShape为空", L"GDMP", L"2024-03-30");
        opGraphicsElementShape->AddChild(TransferOwnership(opBRepShellBody));

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"生成Delaunay三角网格");
        pDirectShape->SetGraphicsElementShape(TransferOwnership(opGraphicsElementShape));
    }

    index++;
    {
        IDirectShape* pDirectShape = IDirectShape::Create(pDocument, BuiltInCategoryUniIdentities::BICU_FORM);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDirectShape, L"pDirectShape为空", L"GDMP", L"2024-03-30");
        OwnerPtr<IGraphicsElementShape> opGraphicsElementShape = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGraphicsElementShape, L"opGraphicsElementShape为空", L"GDMP", L"2024-03-30");

        double charHeight = 500;

        OwnerPtr<IGraphicsRichText> opGRichText = IGraphicsRichText::Create(pDocument, L"GDMP", Vector3d::Zero, 5000, charHeight, false);
        opGRichText->SetCharHeight(charHeight, nullptr);
        opGRichText->SetVerticalAlignmentType(VerticalAlignmentType::Bottom);
        opGRichText->SetHorizontalAlignmentType(HorizontalAlignmentType::Left);

        std::vector<std::pair<OwnerPtr<IPolygon>, TextOutLinePolygonAttribute>> richTextOutLinePolygon = opGRichText->GetRichTextOutLinePolygon();

        for (auto & pair : richTextOutLinePolygon)
        {
            const IPolygon* pPolygon = pair.first.get();
            DBG_WARN_AND_CONTINUE_UNLESS(pPolygon, L"pPolygon为空", L"GDMP", L"2024-03-30");

            // 修复正交轮廓
            OwnerPtr<IPolygon> opRepairedPolygon = nullptr;
            if (pPolygon->IsRegularized() || AlgorithmPolygonOperate::IsPolygonNeedRepair(pPolygon))
            {
                opRepairedPolygon = AlgorithmPolygonOperate::RepairPolygon(pPolygon);
                DBG_WARN_AND_CONTINUE_UNLESS(opRepairedPolygon, L"PolygonRepair fail.", L"GDMP", L"2024-03-30");
                pPolygon = opRepairedPolygon.get();
                DBG_WARN_AND_CONTINUE_UNLESS(pPolygon, L"pPolygon fail.", L"GDMP", L"2024-03-30");
            }

            // 构造坐标系
            Coordinate3d newCoord(pair.second.m_position + Vector3d(0, charHeight, 0), Vector3d::UnitX, Vector3d::UnitY);

            // 图形节点
            OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBody(newCoord, pPolygon, newCoord.Z(), 0.0, 300);
            DBG_WARN_AND_CONTINUE_UNLESS(opBody, L"opBody为空", L"GDMP", L"2024-03-30");

            OwnerPtr<IGraphicsBRepBody > opBrepBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
            DBG_WARN_AND_CONTINUE_UNLESS(opBrepBody, L"opBrepBody为空", L"GDMP", L"2024-03-30");

            opGraphicsElementShape->AddChild(TransferOwnership(opBrepBody));
        }

        TransformAndMark(pDocument, opGraphicsElementShape.get(), index, L"生成Delaunay三角网格");
        pDirectShape->SetGraphicsElementShape(TransferOwnership(opGraphicsElementShape));
    }

    index++;
    {
        IGraphicsStyle* pStyleElem = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pStyleElem, L"pStyleElem为空", L"GDMP", L"2024-03-30");
        OwnerPtr<IGraphicsStyleData> opGStyleData = IGraphicsStyleData::Create();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGStyleData, L"opStyleData为空", L"GDMP", L"2024-03-30");
        opGStyleData->SetProjectionLineColor(Color::OliveDrab);
        pStyleElem->SetGraphicsStyleData(*opGStyleData);

        OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Annotation);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrep, L"IGraphicsElementShape::Create()失败", L"GDMP", L"2024-03-30");

        Vector3d position = GetPosition(index) + Vector3d(500, 500, 0);
        Coordinate3d coord = Coordinate3d::CreateFromAxis(position, Vector3d::UnitX, Vector3d::UnitY);

        {
            // 创建zoomfree节点
            OwnerPtr<IGraphicsZoomFree> opZoomFree = IGraphicsZoomFree::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opZoomFree, L"opZoomFree创建失败", L"GDMP", L"2024-03-30");
            // 创建NodeGroup
            OwnerPtr<IGraphicsNodeGroup> opGNodeGroup = IGraphicsNodeGroup::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGNodeGroup, L"opGNodeGroup为空", L"GDMP", L"2024-03-30");
            {
                // 圆柱
                OwnerPtr<IBody> opCylinder = GmBodyBuilder::CreateSolidCylinder(Vector3d::Zero, Vector3d::UnitZ * 100, 10);
                DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opCylinder, L"opCylinder为空", L"GDMP", L"2024-03-30");
                OwnerPtr<IGraphicsBRepBody> opGBrepCylinder = IGraphicsBRepBody::Create(TransferOwnership(opCylinder));
                DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGBrepCylinder, L"opGBrepCylinder为空", L"GDMP", L"2024-03-30");
                opGNodeGroup->AddChild(TransferOwnership(opGBrepCylinder));

                // 圆锥
                OwnerPtr<IBody> opCone = GmBodyBuilder::CreateConeBody(Vector3d::UnitZ * 100, Vector3d::UnitZ * 150, 30);
                DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opCone, L"opConee为空", L"GDMP", L"2024-03-30");
                OwnerPtr<IGraphicsBRepBody> opGBrepCone = IGraphicsBRepBody::Create(TransferOwnership(opCone));
                DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGBrepCone, L"opGBrepCone为空", L"GDMP", L"2024-03-30");
                opGNodeGroup->AddChild(TransferOwnership(opGBrepCone));
            }

            opZoomFree->AddChild(TransferOwnership(opGNodeGroup));
            // 设置IGraphicsZoomFree的定位点
            opZoomFree->SetCoordinate(coord);
            opZoomFree->SetGraphicsStyleId(pStyleElem->GetElementId());
            opGrep->AddChild(TransferOwnership(opZoomFree));
        }
        {
            // 创建zoomfree节点
            OwnerPtr<IGraphicsZoomFree> opZoomFree = IGraphicsZoomFree::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opZoomFree, L"opZoomFree创建失败", L"GDMP", L"2024-03-30");
            OwnerPtr<IArc3d> opArc = IArc3d::Create(Vector3d::Zero, Vector3d(50, 0, 0), Vector3d(25, 25, 0));
            OwnerPtr<IGraphicsCurve3d> opGCrv = IGraphicsCurve3d::Create(opArc.get());
            opZoomFree->AddChild(TransferOwnership(opGCrv));
            opZoomFree->SetCoordinate(coord);
            opZoomFree->SetGraphicsStyleId(pStyleElem->GetElementId());
            opGrep->AddChild(TransferOwnership(opZoomFree));
        }
        {
            // 创建zoomfree节点
            OwnerPtr<IGraphicsZoomFree> opZoomFree = IGraphicsZoomFree::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opZoomFree, L"opZoomFree创建失败", L"GDMP", L"2024-03-30");
            std::wstring fontPath = FileSystem::GetExeDirPath() + L"FZLTHJW.TTF";
            Vector3d textPosition(20, 0, 0);
            Vector3d textDirection = Vector3d::UnitX;
            Vector3d textNormal = Vector3d::UnitZ;
            double textHeight = 10;

            AnnotationTextData textData = { L"ZoomFree", fontPath, textPosition, textDirection, textNormal, textHeight, 0, 1 };
            std::vector<OwnerPtr<IGraphicsText>> opGTexts = IAnnotationText::CreateGraphicsTexts(pDocument, textData);
            OwnerPtr<IGraphicsNodeGroup> opGGroupNode = IGraphicsNodeGroup::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGGroupNode, L"opGGroupNode为空", L"GDMP", L"2024-03-30");
            for (auto &itor : opGTexts)
            {
                opGGroupNode->AddChild(TransferOwnership(itor));
            }
            opZoomFree->AddChild(TransferOwnership(opGGroupNode));
            opZoomFree->SetCoordinate(coord);
            opZoomFree->SetGraphicsStyleId(pStyleElem->GetElementId());
            opGrep->AddChild(TransferOwnership(opZoomFree));
        }

        IPureGraphicsElement* pElement = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGrep));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"GDMP", L"2024-03-30");
        pStyleElem->SetOwnerId(pElement->GetElementId());

        OwnerPtr<GZoomFreeTransformationComponent> opTransformComponent = NEW_AS_OWNER_PTR(GZoomFreeTransformationComponent);
        opTransformComponent->SetOwnerElement(pElement);
        pElement->SetElementTransformationComponent(TransferOwnership(opTransformComponent));
    }

    index++;
    {
        // 创建IGraphicsPicture图形节点
        OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Annotation);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrep, L"IGraphicsElementShape::Create()失败", L"GDMP", L"2024-03-30");

        Vector3d pos = GetPosition(index);
        std::wstring picPath = FileSystem::GetExeDirPath() + L"\\SampleData\\test_grep.png";
        OwnerPtr<IGraphicsPicture> opGPicture = IGraphicsPicture::Create(PictureId::Align, picPath, Vector2i(100, 77), pos);

        opGrep->AddChild(TransferOwnership(opGPicture));

        IPureGraphicsElement* pElement = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGrep));
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"GDMP", L"2024-03-30");
    }

    index++;
    {
        // 创建两条交叉直线，一条红线，一条蓝线。可以用于测试渲染优先级
        {
            IGraphicsStyle* pStyleElem = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pStyleElem, L"pStyleElem为空", L"GDMP", L"2024-03-30");
            OwnerPtr<IGraphicsStyleData> opGStyleData = IGraphicsStyleData::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGStyleData, L"opStyleData为空", L"GDMP", L"2024-03-30");
            opGStyleData->SetProjectionLineColor(Color::Red);
            opGStyleData->SetProjectionLineWidth(10);
            pStyleElem->SetGraphicsStyleData(*opGStyleData);
            OwnerPtr<ILine3d> opLine = ILine3d::Create(Vector3d(0, 0, 0), Vector3d(1000, 1000, 0));
            OwnerPtr<IGraphicsCurve3d> opGCurve = IGraphicsCurve3d::Create(opLine.get());
            opGCurve->SetGraphicsStyleId(pStyleElem->GetElementId());

            OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrep, L"IGraphicsElementShape::Create()失败", L"GDMP", L"2024-03-30");

            opGrep->AddChild(TransferOwnership(opGCurve));
            TransformAndMark(pDocument, opGrep.get(), index, L"红线");
            // 不能用DirectShape，DirectShape内部会把上面设置的IGraphicsStyleData清除掉
            IPureGraphicsElement* pElement = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGrep));
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"GDMP", L"2024-03-30");
            pStyleElem->SetOwnerId(pElement->GetElementId());
        }

        {
            IGraphicsStyle* pStyleElem = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pStyleElem, L"pStyleElem为空", L"GDMP", L"2024-03-30");
            OwnerPtr<IGraphicsStyleData> opGStyleData = IGraphicsStyleData::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGStyleData, L"opStyleData为空", L"GDMP", L"2024-03-30");
            opGStyleData->SetProjectionLineColor(Color::Blue);
            opGStyleData->SetProjectionLineWidth(10);
            pStyleElem->SetGraphicsStyleData(*opGStyleData);
            OwnerPtr<ILine3d> opLine = ILine3d::Create(Vector3d(1000, 0, 0), Vector3d(0, 1000, 0));
            OwnerPtr<IGraphicsCurve3d> opGCurve = IGraphicsCurve3d::Create(opLine.get());
            opGCurve->SetGraphicsStyleId(pStyleElem->GetElementId());

            OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrep, L"IGraphicsElementShape::Create()失败", L"GDMP", L"2024-03-30");

            opGrep->AddChild(TransferOwnership(opGCurve));
            TransformAndMark(pDocument, opGrep.get(), index, L"____蓝线");
            // 不能用DirectShape，DirectShape内部会把上面设置的IGraphicsStyleData清除掉
            IPureGraphicsElement* pElement = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGrep));
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"GDMP", L"2024-03-30");
            pStyleElem->SetOwnerId(pElement->GetElementId());
        }
    }

    index++;
    {
        // 创建两个部分重叠的正方形，一个红色，一个蓝色。可以用于测试渲染优先级
        {
            IGraphicsStyle* pStyleElem = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pStyleElem, L"pStyleElem为空", L"GDMP", L"2024-03-30");
            OwnerPtr<IGraphicsStyleData> opGStyleData = IGraphicsStyleData::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGStyleData, L"opGStyleData为空", L"GDMP", L"2024-03-30");
            opGStyleData->SetProjectionLineColor(Color::Red);
            opGStyleData->SetProjectionLineWidth(10);
            opGStyleData->SetProjectionFaceHatchPattern(L"SOLID");
            opGStyleData->SetProjectionFaceHatchColor(Color::Orange);
            opGStyleData->SetColor(Color::Orange);
            pStyleElem->SetGraphicsStyleData(*opGStyleData);

            OwnerPtr<IPlane> opPlane = IPlane::Create(Vector3d::Zero, Vector3d::UnitZ);
            std::vector<gcmp::Vector2d> points = { Vector2d(0, 0), Vector2d(800, 0), Vector2d(800, 800), Vector2d(0, 800), Vector2d(0, 0) };
            OwnerPtr<IPolyCurve> opPolyCurve = IPolyCurve::Create(points);
            OwnerPtr<IPolygon> opPolygon = IPolygon::Create();
            opPolygon->AddPolyCurveByClone(opPolyCurve.get());

            OwnerPtr<IBody> opBody = GmBodyBuilder::CreateShell(opPlane.get(), opPolygon.get());
            OwnerPtr<IGraphicsBRepBody> opGBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
            opGBody->SetGraphicsStyleId(pStyleElem->GetElementId());

            OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrep, L"IGraphicsElementShape::Create()失败", L"GDMP", L"2024-03-30");

            opGrep->AddChild(TransferOwnership(opGBody));
            TransformAndMark(pDocument, opGrep.get(), index, L"红色矩形");

            IPureGraphicsElement* pElement = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGrep));
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"GDMP", L"2024-03-30");
            pStyleElem->SetOwnerId(pElement->GetElementId());
        }

        {
            IGraphicsStyle* pStyleElem = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pStyleElem, L"pStyleElem为空", L"GDMP", L"2024-03-30");
            OwnerPtr<IGraphicsStyleData> opGStyleData = IGraphicsStyleData::Create();
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGStyleData, L"opGStyleData为空", L"GDMP", L"2024-03-30");
            opGStyleData->SetProjectionLineColor(Color::Blue);
            opGStyleData->SetProjectionLineWidth(10);
            opGStyleData->SetProjectionFaceHatchPattern(L"SOLID");
            opGStyleData->SetProjectionFaceHatchColor(Color::SteelBlue);
            opGStyleData->SetColor(Color::SteelBlue);
            pStyleElem->SetGraphicsStyleData(*opGStyleData);

            OwnerPtr<IPlane> opPlane = IPlane::Create(Vector3d::Zero, Vector3d::UnitZ);
            std::vector<gcmp::Vector2d> points = { Vector2d(1000,1000), Vector2d(200, 1000), Vector2d(200, 200), Vector2d(1000, 200), Vector2d(1000,1000) };
            OwnerPtr<IPolyCurve> opPolyCurve = IPolyCurve::Create(points);
            OwnerPtr<IPolygon> opPolygon = IPolygon::Create();
            opPolygon->AddPolyCurveByClone(opPolyCurve.get());

            OwnerPtr<IBody> opBody = GmBodyBuilder::CreateShell(opPlane.get(), opPolygon.get());
            OwnerPtr<IGraphicsBRepBody> opGBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
            opGBody->SetGraphicsStyleId(pStyleElem->GetElementId());

            OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opGrep, L"IGraphicsElementShape::Create()失败", L"GDMP", L"2024-03-30");

            opGrep->AddChild(TransferOwnership(opGBody));
            TransformAndMark(pDocument, opGrep.get(), index, L"______蓝色矩形");

            IPureGraphicsElement* pElement = IPureGraphicsElement::Create(pDocument, TransferOwnership(opGrep));
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"GDMP", L"2024-03-30");
            pStyleElem->SetOwnerId(pElement->GetElementId());
        }
    }
    index++;
    {
        OwnerPtr<IGraphicsStyleData> opStyleData = IGraphicsStyleData::Create();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opStyleData, L"opStyleData为空", L"GDMP", L"2024-03-30");

        // 设置投影边线：紫色半透明虚线，线宽采用定宽度，线宽为0.5毫米（打印到图纸为0.5毫米）
        Color projectLineColor = Color::Purple;
        projectLineColor.A = 126;
        opStyleData->SetProjectionLineColor(projectLineColor);
        opStyleData->EnableProjectionLineColorAlpha(true);
        opStyleData->SetProjectionLineTypeName(L"DASHED");
        opStyleData->SetProjectionLineWidth(0.5);
        opStyleData->SetProjectionLineTypeScale(2);
        opStyleData->SetProjectionLineWidthMode(LineWidthMode::WORLD);

        // 设置剖切线：绿色半透明虚线，线宽采用定像素，线宽为5像素
        opStyleData->SetSectionLineColor(Color::Green);
        opStyleData->SetSectionLineTypeName(L"DASHED");
        opStyleData->SetSectionLineWidth(5);
        opStyleData->SetSectionLineWidthMode(LineWidthMode::PIXEL);
        opStyleData->SetSectionLineTypeScale(3);

        // 设置透明度（包括投影面和剖切面）
        opStyleData->SetTransparency(0.8);

        // 设置投影面颜色为黄色
        opStyleData->SetColor(Color::Yellow);

        // 设置剖切面底色为浅灰，十字花绿色填充，填充旋转45度
        opStyleData->SetSectionFaceColor(Color::LightGray).SetSectionFaceHatchPattern(L"CROSS").SetSectionFaceHatchColor(Color::Green)
            .SetSectionFaceHatchScale(8).SetSectionFaceHatchRotation(Constants::MATH_PI_4);

        // 用上面创建的IGraphicsStyleData创建针对整个图元体块的显示样式
        IGraphicsStyle* pStyleElem = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pStyleElem, L"pStyleElem为空", L"GDMP", L"2024-03-30");
        pStyleElem->SetGraphicsStyleData(*opStyleData);

        // 用上面的IGraphicsStyleData继续修改，用作体块顶面的显示样式
        // 体块顶面的显示样式：投影面有斜线红色填充，30度旋转。
        opStyleData->SetProjectionFaceHatchPattern(L"ANSI31");
        opStyleData->SetProjectionFaceHatchColor(Color::Red);
        opStyleData->SetProjectionFaceHatchLineWidth(2);
        opStyleData->SetProjectionFaceHatchScale(10);
        opStyleData->SetProjectionFaceHatchRotation(Constants::MATH_PI_6);

        // 创建针对体块顶面的显示样式
        IGraphicsStyle* pFaceGStyle = IGraphicsStyle::Create(pDocument, ElementCreationOptions::Normal);
        pFaceGStyle->SetGraphicsStyleData(*opStyleData);

        // 创建体块的IGraphicsBRepBody，并设置样式
        std::vector<Vector3d> points = { Vector3d::Zero, Vector3d(1000, 0, 0), Vector3d(1000, 1000, 0), Vector3d(0, 1000,0) };
        OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBodyByPoints(points, 1000);
        OwnerPtr<IGraphicsBRepBody> opGBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));
        opGBody->SetGraphicsStyleId(pStyleElem->GetElementId());

        // 对体块顶面单独设置样式
        IGraphicsBRepFace* pBRepFace = opGBody->GetFaceFW(1);
        pBRepFace->SetGraphicsStyleId(pFaceGStyle->GetElementId());

        // 完成IDirectShape，通过IElementModelShape::SetGraphicsElementShape可以保留显示样式
        // IDirectShape::SetGraphicsElementShape会删除图形节点上设置的样式
        OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);
        opGrep->AddChild(TransferOwnership(opGBody));

        TransformAndMark(pDocument, opGrep.get(), index, L"显示样式");

        IDirectShape* pDiretShape = IDirectShape::Create(pDocument, BuiltInCategoryUniIdentities::BICU_FORM, ElementCreationOptions::Normal);
        IElement* pOwnerElement = pDiretShape->GetOwnerElement();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pOwnerElement, L"pElement为空", L"GDMP", L"2024-03-30");
        IElementModelShape* pElemModelShape = pOwnerElement->GetElementModelShape();
        pElemModelShape->SetGraphicsElementShape(TransferOwnership(opGrep));

        // 上面创建的两个IGraphicsStyle仅用于该图元，SetOwnerId可以在图元删除时自动删除IGraphicsStyle
        pStyleElem->SetOwnerId(pOwnerElement->GetElementId());
        pFaceGStyle->SetOwnerId(pOwnerElement->GetElementId());
    }

    index++;
    {
        std::vector<Vector3d> points = { Vector3d::Zero, Vector3d(1000, 0, 0), Vector3d(1000, 1000, 0), Vector3d(0, 1000,0) };
        OwnerPtr<IBody> opBody = GmBodyBuilder::CreateExtrudeBodyByPoints(points, 1000);
        OwnerPtr<IGraphicsBRepBody> opGBody = IGraphicsBRepBody::Create(TransferOwnership(opBody));

        OwnerPtr<IGraphicsElementShape> opGrep = IGraphicsElementShape::Create(GraphicsRenderLayer::Model);

        opGrep->AddChild(TransferOwnership(opGBody));

        TransformAndMark(pDocument, opGrep.get(), index, L"该图元使用：用于图形节点按照样式类别重载的类别");

        IDirectShape* pDiretShape = IDirectShape::Create(pDocument, CustomizerGStyleManager::s_category_id_CategoryA, ElementCreationOptions::Normal);
        IElement* pOwnerElement = pDiretShape->GetOwnerElement();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pOwnerElement, L"pElement为空", L"GDMP", L"2024-03-30");
        IElementModelShape* pElemModelShape = pOwnerElement->GetElementModelShape();
        pElemModelShape->SetGraphicsElementShape(TransferOwnership(opGrep));
    }

    index++;
    {
        SampleViewSpecificElement* pViewSpecificElem = SampleViewSpecificElement::Create(pDocument);
    }

    index++;
    opTransaction->Commit();

    // 需要刷新视图后，然后缩放视图到现有模型才起效果
    IUiView* pCurrentView = UiDocumentViewUtils::GetCurrentUiView();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pCurrentView, L"pCurrentView为空", L"GDMP", L"2024-03-30");
    pCurrentView->GetCanvas()->Refresh();

    ICommandManager* pCommandManager = ICommandManager::Get();
    pCommandManager->SendCommand(L"gmZoomFitCmd");

    return nullptr;
}

